//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:20-4-18
// @Time:下午1:38
//

#ifndef GEEJOAN_SECURITYCOMMON_H
#define GEEJOAN_SECURITYCOMMON_H

#include <cstdint>
#include <cstddef>
#include <string>
/**
 * @brief 通用工具安全类 需要openssl 支持
 */


#define  COMMON_KEY_PAIR_SIZE           32
#define  COMMON_SIGNATURE_SIZE          64
#define  COMMON_SIGNATURE_RAMDON_SIZE   64

namespace GeeJoan
{
    namespace Common
    {
        enum CIPHER_AES_TYPE{
            CIPHER_AES_CBC_PKCS5 = 1, ///< AES CBC
            CIPHER_AES_CTR_NOPADDING = 2  ///< AES CTR
        };

        enum COMMON_ERROR_CODE_TYPE{
            COMMON_ERROR_CODE_SUCCESS = 0 , ///< 成功
            COMMON_ERROR_CODE_FAIL = -1 , ///< 通用错误
            COMMON_ERROR_CODE_UNKNOW = -2 , ///< 未知错误
            COMMON_ERROR_CODE_NOMEM = -3 , ///< 没内存
            COMMON_ERROR_CODE_INVAL = -4 , ///< 初始化失败
        };
        /**
         * @brief 随机数生成
         * @param[out] data byte指针
         * @param[in] len 产生的长度
         * @param[in] user_data 用户数据
         * @return 错误码
         */
        int common_random_generator(uint8_t *data, size_t len, void *user_data = nullptr);

        int common_hmac_sha256_init(void **hmac_context, const std::string &key, void *user_data = nullptr);

        int common_hmac_sha256_update(void *hmac_context, const std::string &data, void *user_data = nullptr);

        int common_hmac_sha256_final(void *hmac_context, std::string &outBuffer, void *user_data = nullptr);

        void common_hmac_sha256_cleanup(void *hmac_context, void *user_data = nullptr);


        /**
         * @brief 基础封装
         * @param key
         * @param seed
         * @param outBuffer
         * @return
         */
        int common_hmac_sha256_base(const std::string &key, const std::string &seed, std::string &outBuffer);


        int common_sha512_digest_init(void **digest_context, void *user_data = nullptr);

        int common_sha512_digest_update(void *digest_context,
                                        const std::string data,
                                        void *user_data = nullptr);

        int common_sha512_digest_final(void *digest_context, std::string &outBuffer, void *user_data = nullptr);

        void common_sha512_digest_cleanup(void *digest_context, void *user_data = nullptr);

        /**
         * @brief 封装
         * @param input
         * @param outBuffer
         * @return
         */
        int common_sha512_digest_base(const std::string &input, std::string &outBuffer);

        int64_t jenkins_hash(const char *key, size_t len);


        int common_encrypt(std::string &outBuffer,
                           CIPHER_AES_TYPE cipher,
                           const uint8_t *key, size_t key_len,
                           const uint8_t *iv, size_t iv_len,
                           const uint8_t *plaintext, size_t plaintext_len,
                           void *user_data = nullptr);

        int common_decrypt(std::string &outBuffer,
                           CIPHER_AES_TYPE cipher,
                           const uint8_t *key, size_t key_len,
                           const uint8_t *iv, size_t iv_len,
                           const uint8_t *ciphertext, size_t ciphertext_len,
                           void *user_data = nullptr);

        // TODO MD5 的 封装
    }
}


#endif //GEEJOAN_SECURITYCOMMON_H
